/*
 * 12内存常见问题.c
 *
 *  Created on: 2024年3月14日
 *      Author: sulei_zhang
 */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

int main0812(){
	// 数组下标越界问题
	char* p = (char*)malloc(sizeof(char)*11); // 开辟11个字节的空间
	strcpy(p, "hello world"); // 拷贝12个字节到p
	printf("%s\n", p); // 打印是没问题的
	// free(p); // 释放会出问题，因为申请了11个字节，但用了12个字节，释放的时候又要释放11个字节
	return 0;
}

int main081201(){
	int* p = (int*)malloc(0); // 申请0个字节的空间
	printf("%p\n", p); // 不会报错
	*p = 100;
	printf("%d\n", *p); // 打印出100
	// free(p); // 会报错，申请了0个字节，但用了4个字节，此时要释放0个字节则失败
	return 0;
}

int main081202(){
	int* p = (int*)malloc(sizeof(int)*10); // 2个半整型空间
	p[0] = 123;
	p[1] = 456;
	printf("%p\n", p);
	printf("%d\n", *p);
	printf("%d\n", *(p+1));
	// free(p);
	return 0;
}

int main081203(){
	int* p = (int*)malloc(sizeof(int)*10);
	free(p);
	// free(p); // 不允许多次释放
	// 除非先执行p = NULL; 空指针可以多次释放
	p = NULL;
	free(p);
	return 0;
}

int main081204(){
	int* p = (int*)malloc(sizeof(int)*10);
	for(int i=0; i<10; i++){
		*p = i;
		// 指针叠加，不断改变指针方向，释放会出错；如果一定要修改，则做一个备份
		p++;
	}
}

void fun08(int* p){
	p = (int*)malloc(sizeof(int)*10);
	// 这个形参本质上是实参的拷贝，对形参的操作不会影响到实参
	printf("形参：%p\n", p);
}

int main081205(){
	int* p = NULL;
	fun08(p);
	// 本质上是值传递，形参不会改变实参的值，要按下面fun09改
	printf("实参：%p\n", p);
	return 0;
}

// int* p是指针；int** p则指向了p的堆空间
void fun09(int** p){
	// 把这个地址指向了新开辟的地址空间
	*p = (int*)malloc(sizeof(int)*10);
	printf("形参：%p\n", *p);
}

int main081206(){
	int* p = NULL;
	// 传入的是指针的地址
	fun09(&p);
	// 本质上是值传递，形参不会改变实参的值，要按下面fun09改
	printf("实参：%p\n", p);
	return 0;
}
